package ro.flashbite.helpers
{
	import ro.flashbite.errors.ArgumentIncompatibleError;
	import ro.flashbite.errors.DontInstanciateError;
	
	import flash.utils.Dictionary;

	/**
	 * Static helpers for working with Dictionary objects
	 * 
	 * v 1.0
	 * 
	 * @author Adrian Barbu
	 */	
	public final class DictionaryHelpers
	{
		public function DictionaryHelpers() { throw new DontInstanciateError(); }
		
		/**
		 * Concat two or more dictionaries 
		 * 
		 * @param dicts : (Array) dictionaries to concat
		 * @parm useWeakRef : (Boolean) weak reference from any Dictionary contructor
		 * @return : (Dictionary) the final dictionary maked by concating all given dictionaries
		 */
		public static function concat(useWeakRef:Boolean = false, ...dicts):Dictionary
		{
			if (dicts == null){
				throw new ArgumentIncompatibleError("dicts");
			}
			
			var finDict    : Dictionary = new Dictionary(useWeakRef),
				len        : int = dicts.length,
				i          : int,
				key        : *,
				auxDict    : Dictionary;
			
			for (i=0; i < len ;i++){                    
				auxDict =   dicts[i] as Dictionary;
				if (auxDict) {		                
					for (key in auxDict) {
						finDict[key] = auxDict[key];
					}
				}                    
			}
			return finDict;
		}
		
		/**
		 * Remove all data from dictionary
		 * 
		 * @param dict: (Dictionary) the dictionary to be clear'ed
		 */
		static public function clear(dict:Dictionary):void
		{
			if (dict == null){
				throw new ArgumentIncompatibleError("dicts");
			}
			
			var key : *;
			for (key in dict) {
				dict[key] = null;
				delete dict[key];
			}
		}
		
		/**
		 * Gets the number of elements of the dictionary
		 *  
		 * @param dict : (Dictionary) the dictionary used to get the length
		 * @return : (uint) the length of dictionary
		 */
		static public function length(dict:Dictionary):uint
		{
			if (dict == null){
				throw new ArgumentIncompatibleError("dicts");
			}
			
			var key : *,
				len : int = 0;
			for (key in dict) len++;
			
			return len;
		}
		
		/**
		 * Gets a clone of the dictionary 
		 * 
		 * @param dict : (Dictionary) dictionary used to clone
		 * @parm useWeakRef : (Boolean) weak reference from any Dictionary contructor
		 * @return : (Dictionary) a cloned dictionary
		 */
		static public function clone(dict:Dictionary, useWeakRef:Boolean = false):Dictionary
		{
			if (dict == null){
				throw new ArgumentIncompatibleError("dicts");
			}
			
			var res	: Dictionary = new Dictionary(useWeakRef),
				key : *;
			for (key in dict) {
				res[key] = dict[key];
			}
			
			return res;
		}	
		
		/**
		 * Gets a swap-'clone' of the dictionary
		 *  
		 * @param dict : (Dictionary) dictionary used to clone
		 * @parm useWeakRef : (Boolean) weak reference from any Dictionary contructor
		 * @return : (Dictionary) the swaped-'cloned' dictionary with the same type of reference
		 */
		static public function swapClone(dict:Dictionary, useWeakRef:Boolean = false):Dictionary
		{
			if (dict == null){
				throw new ArgumentIncompatibleError("dicts");
			}
			
			
			var res	: Dictionary = new Dictionary(useWeakRef),
				key : *;
			for (key in dict) {
				res[dict[key]] = key;
			}
			
			return res;
		}	
	}
}